package com.beanverify.inter.impl;


import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.beanverify.inter.AnnotationBox;
import com.beanverify.inter.AnnotationVerifier;
import com.beanverify.inter.BeanChecker;
import com.beanverify.inter.VerifyResult;
import com.beanverify.utils.AnnotationUtils;


/**
 * 
 */
public class MyBeanChecker implements BeanChecker{
	private static Logger LOG = LoggerFactory.getLogger(MyBeanChecker.class);
	private AnnotationBox annotationBox = new MyAnnotationBox();
	private static MyBeanChecker beanChecker = new MyBeanChecker();

	public VerifyResult doVerify(Object bean) {
		Field[] fields = bean.getClass().getDeclaredFields();
		for(Field f : fields) {
			f.setAccessible(true);
			VerifyResult result;
			try {
				result = doVerify(f.get(bean), f.getName(), f.getDeclaredAnnotations());
				if (false == result.isSuccess()){
					return result;
				} else continue;
			} catch (Exception e) {
				LOG.error("Exception",e);
				return MyVerifyResult.DEFAULT_FAILED;
			}
		}
		return MyVerifyResult.DEFAULT_SUCCESS;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private VerifyResult doVerify(Object param, String paramName,Annotation[] annotations){
		for (Annotation annotation : annotations) {
			Map<String, Object> map = AnnotationUtils.getAnnotationAttributes(annotation);
			AnnotationVerifier validator = annotationBox.getAnno(annotation.getClass());
			try {
				if (null == validator){
					String mapClazz = map.get("mapClazz").toString();
					validator = (AnnotationVerifier)Class.forName(mapClazz).newInstance();
					annotationBox.addNewAnno(annotation.getClass(), validator.getClass());
				}
			} catch (Exception e) {
				LOG.error("Exception",e);
				return MyVerifyResult.DEFAULT_FAILED;
			}
			try {
				VerifyResult result = validator.doVerify(param, paramName, annotation);
				if (false == result.isSuccess()){
					return result;
				} else continue;
			} catch (Exception e) {
				LOG.error("Exception",e);
				return MyVerifyResult.DEFAULT_FAILED;
			}
		}
		return MyVerifyResult.DEFAULT_SUCCESS;
	}

	public VerifyResult doCheckBean(Object bean) {
		return doVerify(bean);
	}

	public static VerifyResult doCheck(Object bean){
		return beanChecker.doCheckBean(bean);
	}
}
